package io.xxx.omni.osc.sync

import com.alibaba.fastjson.JSONObject
import io.xxx.omni.osc.common.dateTimeFormatter
import io.xxx.omni.osc.common.toJSONObject
import io.xxx.omni.osc.common.toLocalDateTime
import io.xxx.omni.osc.domain.*
import io.xxx.omni.osc.sdk.BbClient
import org.springframework.stereotype.Component
import java.time.LocalDateTime

/**
 * 贝贝
 */
abstract class BbPorter : GenericPageDocumentPorter(), PlatformIdentity.BeiBei {

    protected abstract val method: String

    override val pageSize = 300

    override fun getParameters(store: Store): Pair<List<Any>, Boolean> = listOf("modified_time") to false

    override fun getCount(context: JobContext, response: JSONObject): Int = response.getInteger("count")

    override fun getResponse(context: JobContext, pageNo: Int, hasTotal: Boolean): JSONObject {
        val (store, startTime, endTime, parameter) = context
        val request = buildRequest(startTime, endTime, parameter, pageNo)
        val client = applicationContext.getBean(BbClient::class.java)
        val response = client.execute(store, method, request)
        val errCode = response.getString("err_code")
        if (errCode != null) {
            throwException(context, request, response)
        }
        return response
    }

    private fun buildRequest(
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Int
    ): Map<String, Any> {
        return mapOf(
            "time_range" to parameter!!,
            "start_time" to startTime.format(dateTimeFormatter),
            "end_time" to endTime.format(dateTimeFormatter),
            "page_no" to pageNo,
            "page_size" to pageSize,
        )
    }
}

// 订单
@Component
class BbTradePorter : BbPorter() {

    override val documentType = DocumentType.TRADE

    override val method = "beibei.outer.trade.order.get"

    override fun getStartTime(store: Store, jobCheckpoint: JobCheckpoint): LocalDateTime {
        val minStartTime = LocalDateTime.now().minusDays(30).plusMinutes(1)
        val startTime = jobCheckpoint.endTime
        return if (startTime < minStartTime) minStartTime else startTime
    }

    override fun buildDocuments(context: JobContext, response: JSONObject): List<Document> {
        return response
            .getJSONArray("data")
            .map {
                val value = it.toJSONObject()
                val sn = value.getString("oid")
                val status = value.getString("status")
                val modified = value.getString("modified_time").toLocalDateTime()
                Document(sn, status, modified, value)
            }
    }
}

// 退单
@Component
class BbRefundPorter : BbPorter() {

    override val documentType = DocumentType.REFUND

    override val method = "beibei.outer.refunds.get"

    override fun buildDocuments(context: JobContext, response: JSONObject): List<Document> {
        return response
            .getJSONArray("data")
            .map {
                val value = it.toJSONObject()
                val sn = value.getString("id")
                val rsn = value.getString("oid")
                val status = value.getString("status")
                val modified = value.getString("modified_time").toLocalDateTime()
                Document(sn, rsn, status, modified, value)
            }
    }
}